package com.linkoog.devtools.http.linemarker;

import com.intellij.codeInsight.daemon.LineMarkerInfo;
import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.ActionGroup;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.editor.markup.MarkupEditorFilter;
import com.intellij.openapi.editor.markup.MarkupEditorFilterFactory;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.util.Function;
import com.linkoog.devtools.http.common.HttpMethod;
import com.linkoog.devtools.http.linemarker.action.HttpQuickTestAction;
import com.linkoog.devtools.http.raw_index.HttpServiceMethod;
import com.linkoog.devtools.http.raw_index.HttpServiceMethodRawFileIndex;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.util.Collection;
import java.util.List;



public class HttpTestLineMarkerProvider extends LineMarkerProviderDescriptor {


    @Override
    public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
        Project project = element.getProject();
        if (!(element instanceof PsiMethod)) return null;

        final PsiMethod psiMethod = (PsiMethod) element;
        if (!psiMethod.isValid()) return null;

        final PsiClass psiClass = psiMethod.getContainingClass();
        if (psiClass == null || !psiClass.isValid()) return null;

        final HttpServiceMethodRawFileIndex httpServiceMethodRawFileIndex = HttpServiceMethodRawFileIndex.getInstance(project);
        final HttpMethod httpMethod = httpServiceMethodRawFileIndex.parseHttpMethod(psiMethod);
        if (httpMethod == null) return null;

        DefaultActionGroup actionGroup = new DefaultActionGroup();


        // 接口测试
        Icon runIcon = AllIcons.Actions.Execute;
        HttpQuickTestAction quickTestAction = new HttpQuickTestAction(psiMethod,"Run Http Test", null, runIcon);
        actionGroup.add(quickTestAction);

        // markdown 文档
        /*actionGroup.addSeparator();
        MarkdownPreviewAction markdownPreviewAction = new MarkdownPreviewAction(httpServiceMethod,"Markdown Preview",null, null);
        actionGroup.add(markdownPreviewAction);

        MarkdownExportAction markdownExportAction = new MarkdownExportAction(httpServiceMethod,"Markdown Export",null, null);
        actionGroup.add(markdownExportAction);



        // 上传文档管理平台
        actionGroup.addSeparator();
        YapiDocUploadAction yapiDocUploadAction = new YapiDocUploadAction(httpServiceMethod,"Upload doc to yapi",null, Icons.YAPI_16);
        actionGroup.add(yapiDocUploadAction);

        Rap2DocUploadAction rap2DocUploadAction = new Rap2DocUploadAction("Upload doc to rap2",null, Icons.UPLOAD);
        actionGroup.add(rap2DocUploadAction);

        ShowdocDocUploadAction showdocDocUploadAction = new ShowdocDocUploadAction(httpServiceMethod,"Upload doc to showdoc",null, Icons.UPLOAD);
        actionGroup.add(showdocDocUploadAction);*/


        Icon httpMethodIcon = httpMethod.getIcon();
        return new RunLineMarkerInfo(psiMethod.getNameIdentifier(), httpMethodIcon, t -> "Http 接口", actionGroup);
    }

    static class RunLineMarkerInfo extends LineMarkerInfo<PsiElement> {
        private final DefaultActionGroup myActionGroup;
        private final AnAction mySingleAction;

        RunLineMarkerInfo(PsiElement element, Icon icon, Function<PsiElement, String> tooltipProvider, DefaultActionGroup actionGroup) {
            super(element, element.getTextRange(), icon, tooltipProvider, null, GutterIconRenderer.Alignment.LEFT);
            myActionGroup = actionGroup;
            if (myActionGroup.getChildrenCount() == 1) {
                mySingleAction = myActionGroup.getChildActionsOrStubs()[0];
            } else {
                mySingleAction = null;
            }
        }

        @Override
        public GutterIconRenderer createGutterRenderer() {
            return new LineMarkerGutterIconRenderer<PsiElement>(this) {
                @Override
                public AnAction getClickAction() {
                    return mySingleAction;
                }

                @Override
                public boolean isNavigateAction() {
                    return true;
                }

                @Override
                public ActionGroup getPopupMenuActions() {
                    return myActionGroup;
                }

                @Override
                protected boolean looksTheSameAs(@NotNull LineMarkerGutterIconRenderer<?> renderer) {
                    RunLineMarkerInfo  myInfo = (RunLineMarkerInfo)this.getLineMarkerInfo();

                    LineMarkerInfo lineMarkerInfo = renderer.getLineMarkerInfo();
                    if (lineMarkerInfo instanceof RunLineMarkerInfo){
                        RunLineMarkerInfo  runLineMarkerInfo = (RunLineMarkerInfo) lineMarkerInfo;
                        return super.looksTheSameAs(renderer) && CompareActionGroup(myInfo, runLineMarkerInfo);
                    }

                    return false;
                }

                private boolean CompareActionGroup(RunLineMarkerInfo  myInfo, RunLineMarkerInfo  rendererInfo){
                    return myInfo.getMyActionGroup() != null && rendererInfo.getMyActionGroup() != null &&
                    Comparing.equal(myInfo.getMyActionGroup(), rendererInfo.getMyActionGroup());
                }
            };
        }

        @NotNull
        @Override
        public MarkupEditorFilter getEditorFilter() {
            return MarkupEditorFilterFactory.createIsNotDiffFilter();
        }

        public DefaultActionGroup getMyActionGroup() {
            return myActionGroup;
        }
    }

    @NotNull
    @Override
    public String getName() {
        return "Run http test marker";
    }

}
